package com.choosefine.base.materiel.web.config;

import com.choosefine.base.materiel.common.base.BaseService;
import com.choosefine.base.materiel.common.net.HttpApi;
import com.choosefine.base.materiel.common.utils.MapperFilterUtil;
import com.choosefine.common.url.UrlRegistrar;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.Properties;

/**
 * Created by Qiupeng on 2016/11/10.
 *
 * 加入UrlRegistrarBean
 * @Author Ye_Wenda
 * @Date 2017/04/11
 */
@Configuration
@EnableSwagger2
public class BeanConfig {
    Logger logger = LoggerFactory.getLogger(BeanConfig.class);

    @Value("${dmsUrl}")
    final String dmsUrl = null;

    @Value("${server.context-path}")
    final String serviceName = null;

    @Bean
    public UrlRegistrar urlRegistrar(RequestMappingHandlerMapping requestMappingHandlerMapping, RestTemplate restTemplate) {
        // 在设定了dmsUrl的情况下，去注册URLs
        if (!StringUtils.isEmpty(dmsUrl) && dmsUrl.startsWith("http")) {
            return new UrlRegistrar(requestMappingHandlerMapping, restTemplate, serviceName, dmsUrl);
        }
        return null;
    }
    /**
     * Ignore placeholders that cannot be resolved.
     * */
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        configurer.setIgnoreUnresolvablePlaceholders(true);
        return configurer;
    }
    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        return new RequestMappingHandlerMapping();
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate(redisConnectionFactory);
        setSerializer(template); //设置序列化工具
        template.afterPropertiesSet();
        return template;
    }

    private void setSerializer(StringRedisTemplate template) {
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
    }

    @Bean
    public PageHelper pageHelper() {
        logger.info("注册MyBatis分页插件PageHelper");
        PageHelper pageHelper = new PageHelper();
        Properties p = new Properties();
        p.setProperty("offsetAsPageNum", "true");
        p.setProperty("rowBoundsWithCount", "true");
        p.setProperty("reasonable", "true");
        pageHelper.setProperties(p);
        return pageHelper;
    }

    @Bean
    public Properties yml() {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
        Properties resultProperties = null;
        try {
            logger.info("从<配置文件>中<>读取");
            yaml.setResources(resolver.getResources("classpath*:/**/*.yml"));
            resultProperties = yaml.getObject();
        } catch (Exception e) {
            logger.error("无法读取 yaml 文件", e);
            resultProperties = null;
        }
        return resultProperties;
    }

    @Bean
    public MapperFilterUtil mapperFilterUtil() {
        return new MapperFilterUtil();
    }

    // 跨域设置
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/materiel/**")
                        .allowedMethods("*")
                        .allowedOrigins("*");
            }
        };
    }

    @Bean
    public HttpApi httpApi(){
        return new HttpApi();
    }

    @Bean
    public BaseService baseService(){
        return new BaseService();
    }
}
